﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FrameworkManapro.BusinessModel;

namespace GMAC.ReportingSystem.Business.Components
{
    //--------------------------------------------------------------------------------------
    /// <summary>
    /// Ricardo Recaredo (24/03/2011)
    /// 
    /// Business Logic for CallReasonByAgent entities
    /// 
    /// </summary>
    //---------------------------------------------------------------------------------------

    public class CallReasonByAgentComponent : IBusinessComponent<Entities.CallReasonByAgent>
    {
        #region Attributes

        private DataAccess.CallReasonByAgentDataAccess dac;

        #endregion

        /////////////////////////////////////////////////////////////////

        #region Constructors

        public CallReasonByAgentComponent()
        {
            dac = new DataAccess.CallReasonByAgentDataAccess();
        }

        #endregion

        /////////////////////////////////////////////////////////////////

        #region IBusinessComponent Members

        public int Create(GMAC.ReportingSystem.Business.Entities.CallReasonByAgent entityToCreate)
        {
            throw new NotImplementedException();
        }
       
        //-----------------------------------------------------------------------------------


        public int Delete(GMAC.ReportingSystem.Business.Entities.CallReasonByAgent entityToDelete)
        {
            throw new NotImplementedException();
        }

        //-----------------------------------------------------------------------------------

        public int Edit(GMAC.ReportingSystem.Business.Entities.CallReasonByAgent entityToEdit)
        {
            throw new NotImplementedException();
        }

        //-----------------------------------------------------------------------------------

        public GMAC.ReportingSystem.Business.Entities.CallReasonByAgent GetDetails(object entityId)
        {
            throw new NotImplementedException();
        }

        #endregion

        /////////////////////////////////////////////////////////////////

        #region Public Methods

        public Entities.CallReasonByAgentCollection GetList()
        {
            return dac.GetList();
        }

        //-----------------------------------------------------------------------------------

        public Entities.CallReasonByAgentCollection GetListByDateAndProduct(DateTime dDate, int accountTypeId)
        {
            if (dDate == null)
            {
                throw new NullReferenceException();
            }
            
            return dac.GetListByDateAndProduct(dDate, accountTypeId);
        }

        //-----------------------------------------------------------------------------------

        public bool LoadMultipleCallReasonsByAgent(Entities.CallReasonByAgentCollection callReasonByAgentCollection, int userId)
        {
            if (callReasonByAgentCollection.Count <= 0)
            {
                throw new NullReferenceException();
            }

            return dac.LoadMultipleCallReasonsByAgent(callReasonByAgentCollection, userId);
        }

        //-----------------------------------------------------------------------------------
        /// <summary>
        /// Ricardo Recaredo (25/03/2011)
        /// 
        /// Obtiene una colección de CallReasonByAgent con todos los valores de llamada 
        /// de las posibles combinaciones entre Agentes y Motivos para. A las combinaciones 
        /// de Motivo/Agente que no posean un valor de llamadas asignado, le crea un registro en la
        /// colección y le establece dicho valor como 0.
        /// </summary>
        /// <param name="accountTypeId">Id del Producto</param>
        /// <param name="dDate">Fecha en que se realizaron las llamadas</param> 
        /// <returns>Colección de CallReasonByAgent</returns>
        //-----------------------------------------------------------------------------------

        public Entities.CallReasonByAgentCollection BuildFullCallReasonsByAgentMatrix(int accountTypeId, DateTime dDate, out int numReasons, out int numAgents)
        {
            AgentComponent             agentController           = new AgentComponent();
            CallReasonComponent        callReasonController      = new CallReasonComponent();

            Entities.AgentCollection             agents             = agentController.GetList();
            Entities.CallReasonCollection        callReasons        = callReasonController.GetListByProduct(accountTypeId);
            Entities.CallReasonByAgentCollection callReasonsCurrent = this.GetListByDateAndProduct(dDate, accountTypeId);

            Entities.CallReasonByAgentCollection callReasonsFinal   = new Entities.CallReasonByAgentCollection();

            foreach (Entities.Agent agent in agents)
            { 
                foreach (Entities.CallReason callReason in callReasons)
                {
                    var callReasonInside = (from cr in callReasonsCurrent
                                            where ((cr.Agent.ID == agent.ID) && (cr.CallReason.ID == callReason.ID))
                                            select cr).FirstOrDefault();

                    if (callReasonInside != null)
                    {
                        callReasonsFinal.Add(callReasonInside);
                    }
                    else 
                    {
                        Entities.CallReasonByAgent callReasonNew = new GMAC.ReportingSystem.Business.Entities.CallReasonByAgent
                        {
                            Agent         = agent,
                            CallDate      = dDate,
                            AccountType   = new Entities.Product { AccountTypeID = accountTypeId },
                            CallReason    = callReason,
                            NumberOfCalls = 0
                        };

                        callReasonsFinal.Add(callReasonNew);
                    }
                }

                callReasonsFinal = (from cr in callReasonsFinal 
                                    orderby cr.CallReason.Description, cr.CallReason.ID, cr.Agent.FirstName, cr.Agent.LastName, cr.Agent.ID 
                                    select cr).CreateFromEnumerable<Entities.CallReasonByAgentCollection, Entities.CallReasonByAgent>();
            }

            numReasons = callReasons.Count();
            numAgents  = agents.Count();

            return callReasonsFinal;
        }


        //-----------------------------------------------------------------------------------

        #endregion

    }

    public static class Extensiones
    {
        #region Static Methods

        public static TDerived CreateFromEnumerable<TDerived, T>(this IOrderedEnumerable<T> seq) where TDerived : List<T>, new()
        {
            TDerived outList = new TDerived();
            outList.AddRange(seq);
            return outList;
        }

        #endregion
    }
}
